package edu.cmu.vlis.wassup.publisher;


import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.jms.JMSException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.mybeans.dao.DAOException;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.sun.messaging.Topic;

import edu.cmu.vlis.wassup.databean.Event;
import edu.cmu.vlis.wassup.databean.Location;
import edu.cmu.vlis.wassup.databean.User;
import edu.cmu.vlis.wassup.db.UserDAO;

/**
 * This class will continuously poll the Y! server to get stream of messages.
 */
public class UpcomingPoller extends AbstractPoller{

	Map <Integer,Topic> categoryMap;
	String baseURL;
	private int id;
	public static final String DATE_FORMAT_NOW = "yyyy-MM-dd";
	SimpleDateFormat sdf;

	public UpcomingPoller(Integer port){
		super(port);
		this.id = port;
		this.categoryMap = new HashMap<Integer,Topic>();
		this.baseURL = System.getProperty("upcomingURL");
		//Set the data format
		sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
		this.getCategoryList();


	}


	public void getCategoryList() {
		//Initialize the categories
		StringBuilder queryURL = new StringBuilder(baseURL+"&method=category.getList");
		DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
		domFactory.setNamespaceAware(true); 
		DocumentBuilder builder = null;

		try {
			builder = domFactory.newDocumentBuilder();

		} catch (ParserConfigurationException e) {
			System.err.println("Parser is not configured properly.");
			try {
				out1.write("Parser is not configured properly.\n");
				out1.flush();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			e.printStackTrace();
		}

		Document doc = null;
		try {
			InputSource source = new InputSource(new URL(queryURL.toString()).openStream());
			source.setEncoding("UTF-8");  // Otherwise java may assume different encoding.
			doc = builder.parse(source); // Retrieving xml response and parsing it.
		} catch (SAXException e) {
			System.err.println("Got the response, but failed to parse.");
			try {
				out1.write("Got the response, but failed to parse.\n");
				out1.flush();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			e.printStackTrace();
		} catch (IOException e) {
			System.err.println("Failed to get the response. Check the internet connection");
			try {
				out1.write("Failed to get the response. Check the internet connection\n");
				out1.flush();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			e.printStackTrace();
		}

		XPathFactory xpathFactory = XPathFactory.newInstance();
		XPath xpath = xpathFactory.newXPath();
		XPathExpression expr = null;
		try {
			// x-path expression used here finds all the events in the response
			expr = xpath.compile("//category");
		} catch (XPathExpressionException e) {
			System.err.println("Check the x-path expression. Probably its incorrect");
			e.printStackTrace();
		}
		NodeList categories = null;
		try {
			categories = (NodeList)expr.evaluate(doc, XPathConstants.NODESET); // Here the xpath query will be executed.
		} catch (XPathExpressionException e) {
			System.err.println("Check the x-path expression. Probably its incorrect");
			e.printStackTrace();
		}
		//Iterate thr all the categories and create a topic for each of them.
		for(int i=0; i< categories.getLength(); i++){
			NamedNodeMap map = categories.item(i).getAttributes();
			Node attrId = map.getNamedItem("id");
			Node attrTopic = map.getNamedItem("name");
			Integer catid = new Integer(attrId.getNodeValue());
			if(!this.categoryMap.containsKey(catid))
				try {
					this.categoryMap.put(catid,new Topic(attrTopic.getNodeValue().trim().toLowerCase().replaceAll("[^a-z]", "")));
				} catch (DOMException e) {
					e.printStackTrace();
				} catch (JMSException e) {
					System.err.println("Failed to create topic for Upcoming poller for: "+attrTopic.getNodeValue());
					e.printStackTrace();
				}
		}
	} 

	public int getMessagesNputInPublisherQ(){

		UserDAO userDAO = null;
		Calendar cal = Calendar.getInstance();
		String minDate = "&min_date=" + sdf.format(cal.getTime());
		cal.add(Calendar.DATE,7);
		String maxDate = "&max_date=" + sdf.format(cal.getTime());

		//minDate = "&min_date=2009-03-18";
		//maxDate = "&max_date=2009-06-18";



		int count = 0;
		/*try {
			userDAO = new UserDAO();
		} catch (DAOException e2) {
			e2.printStackTrace();
			return 0;
		} */
		try {
			out1.write("Before!!!");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//ArrayList<Location> locations = userDAO.getLocations();
         Location loc = new Location("Pittsburgh", "PA");
         
		/*if (locations == null) {
			System.err.println("No locations retrieved ... Hence not polling anything ...");
			try {
				out1.write("No locations retrieved ... Hence not polling anything ...");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return 0;
		}
*/
		//for (Iterator<Location> iterator = locations.iterator(); iterator.hasNext();) {
		//	Location loc = (Location) iterator.next();
			if(loc.getCity()!=null) {
				System.err.println("Now polling for " + loc.getCity());
				try{
					this.out1.write("Now polling for " + loc.getCity());
				} catch (IOException e2) {
					// TODO Auto-generated catch block
					e2.printStackTrace();
				}
				StringBuilder queryURL = new StringBuilder(baseURL+"&method=event.search");

				//String searchText = "&search_text=concert";

				String tags = "&tags=rock,music,politics";
				String location =  "&location=" + loc.getCity() + "," + loc.getState();

				queryURL.append(tags);

				queryURL.append(location + minDate + maxDate);

				System.out.println("Query is " + queryURL);
				try {
					this.out1.write("Query is " + queryURL);

					out1.flush();
				} catch (IOException e2) {
					// TODO Auto-generated catch block
					e2.printStackTrace();
				}
				DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
				domFactory.setNamespaceAware(true); 
				DocumentBuilder builder = null;

				try {
					builder = domFactory.newDocumentBuilder();

				} catch (ParserConfigurationException e) {
					System.err.println("Parser is not configured properly.");
					e.printStackTrace();
				}
				Document doc = null;
				try {
					InputSource source = new InputSource(new URL(queryURL.toString()).openStream());
					source.setEncoding("UTF-8");  // Otherwise java may assume different encoding.
					doc = builder.parse(source); // Retrieving xml response and parsing it.
				} catch (SAXException e) {
					System.err.println("Got the response, but failed to parse.");
					e.printStackTrace();
				} catch (IOException e) {
					System.err.println("Failed to get the response. Check the internet connection");
					e.printStackTrace();
				}

				XPathFactory xpathFactory = XPathFactory.newInstance();
				XPath xpath = xpathFactory.newXPath();
				XPathExpression expr = null;
				try {
					// x-path expression used here finds all the events in the response
					expr = xpath.compile("//event");
				} catch (XPathExpressionException e) {
					System.err.println("Check the x-path expression. Probably its incorrect");
					e.printStackTrace();
				}
				NodeList events = null;
				try {
					events = (NodeList)expr.evaluate(doc, XPathConstants.NODESET); // Here the xpath query will be executed.
				} catch (XPathExpressionException e) {
					System.err.println("Check the x-path expression. Probably its incorrect");
					e.printStackTrace();
				}
				//<<<<<<< .mine

				count += events.getLength();

				//=======
				//count += events.getLength();
				//>>>>>>> .r304
				for(int i=0; i< events.getLength(); i++){

					Topic topic = null;
					NamedNodeMap map = events.item(i).getAttributes();
					try {
						Event ann = new Event("");
						for(int j=0; j<map.getLength();j++){
							Node attr = map.item(j);
							if (attr.getNodeName().equalsIgnoreCase("venue_city"))
								ann.setCity(attr.getNodeValue());
							else if (attr.getNodeName().equalsIgnoreCase("name"))
								ann.setName(attr.getNodeValue());
							else if (attr.getNodeName().equalsIgnoreCase("start_date"))
								ann.setStartDate(attr.getNodeValue());
							else if(attr.getNodeName().equalsIgnoreCase("end_date"))
								ann.setEndDate(attr.getNodeValue());
							else if (attr.getNodeName().equalsIgnoreCase("description"))
								ann.setDescription(attr.getNodeValue());
							else if(attr.getNodeName().equalsIgnoreCase("start_time"))
								ann.setStartTime(attr.getNodeValue());
							else if (attr.getNodeName().equalsIgnoreCase("end_time"))
								ann.setEndTime(attr.getNodeValue());
							else if (attr.getNodeName().equalsIgnoreCase("latitude"))
								ann.setLatitude(Float.parseFloat(attr.getNodeValue()));
							else if(attr.getNodeName().equalsIgnoreCase("longitude"))
								ann.setLongitude(Float.parseFloat(attr.getNodeValue()));
							else if (attr.getNodeName().equalsIgnoreCase("venue_state_name"))
								ann.setState(attr.getNodeValue());
							else if (attr.getNodeName().equalsIgnoreCase("venue_address"))
								ann.setStreet(attr.getNodeValue());
							else if(attr.getNodeName().equalsIgnoreCase("url"))
								ann.setUrl(attr.getNodeValue());
							else if(attr.getNodeName().equalsIgnoreCase("category_id")) 
								topic = this.categoryMap.get(Integer.parseInt(attr.getNodeValue().toLowerCase()));
						}
						if(topic!=null )  {
							//                    ann.setSender(null);
							User user = new User("upcoming");
							ann.setSender(user);
							this.topicPublisher.publish(topic,this.topicSession.createObjectMessage(ann));
						}
						else
							System.err.println("No category found for this message.");

					} catch (JMSException e1) {
						e1.printStackTrace();
					} 
				}
			}

		//}
		try {
			out1.write(count+"\n");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return count;
	}
	@Override
	public void startPoller() {
		System.out.println("Poller " + id + " is starting ");
		super.startPoller();
	}
	@Override
	public String getPollerName() {
		return "Upcoming";
	}

	@Override
	public int getID() {
		// TODO Auto-generated method stub
		return id;
	}
}
